Skip to content

Migrate avoid unnecessary return variable rule and its tests#237

Merged
daria-trusca-solid merged 7 commits into
analysis_server_migrationfrom
migrate_avoid_unnecessary_return_variable
Jun 4, 2026
Merged

Migrate avoid unnecessary return variable rule and its tests#237
daria-trusca-solid merged 7 commits into
analysis_server_migrationfrom
migrate_avoid_unnecessary_return_variable

Conversation

@daria-trusca-solid
Copy link
Copy Markdown
Collaborator

Migrated the avoid_unnecessary_return_variable rule and its corresponding tests to comply with the analyzer package.

Changes

  • Rule Refactoring: Updated the implementation of avoid_unnecessary_return_variable to use the current analyzer syntax.
  • Tests: Updated and verified all associated test cases to ensure the rule triggers correctly and no regressions are introduced.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the avoid_unnecessary_return_variable lint rule to extend AnalysisRule and extracts the return variable usage logic into a dedicated ReturnVariableUsageVisitor. Additionally, the test suite has been migrated to a reflective test structure. The review feedback suggests extending SimpleAstVisitor instead of RecursiveAstVisitor in AvoidUnnecessaryReturnVariableVisitor to avoid redundant AST traversal, which also allows for the removal of a redundant super.visitReturnStatement(node) call.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

/// This visitor is searches all uses of a single local variable,
/// including variable declaration.
/// Visitor for [AvoidUnnecessaryReturnVariableRule].
class AvoidUnnecessaryReturnVariableVisitor extends RecursiveAstVisitor<void> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since this visitor is registered via registry.addReturnStatement to process specific nodes, it does not need to recursively traverse the entire AST. Changing the base class to SimpleAstVisitor avoids redundant traversal and improves performance.

Suggested change
class AvoidUnnecessaryReturnVariableVisitor extends RecursiveAstVisitor<void> {
class AvoidUnnecessaryReturnVariableVisitor extends SimpleAstVisitor<void> {

Comment on lines +55 to +57
rule.reportAtNode(node);

super.visitReturnStatement(node);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calling super.visitReturnStatement(node) is redundant when using SimpleAstVisitor and registered via registry.addReturnStatement. Furthermore, it was applied inconsistently as it was skipped in several early return paths. Removing it simplifies the code and ensures consistent behavior.

Suggested change
rule.reportAtNode(node);
super.visitReturnStatement(node);
rule.reportAtNode(node);

Copy link
Copy Markdown
Contributor

@danylo-safonov-solid danylo-safonov-solid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small suggestions, seems good otherwise

Comment on lines +43 to +44
lintName,
lintMessage,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can inline those the same way as I proposed in #238

Comment on lines +19 to +30
if (expr is! SimpleIdentifier) {
return;
}

final ReturnStatement _returnStatement;
final element = expr.element;
if (element is! LocalVariableElement) {
return;
}

/// After visiting holds info about whether there are any tokens
/// between variable declaration and return statement
bool get foundTokensBetweenDeclarationAndReturn =>
_foundTokensBetweenDeclarationAndReturn;
if (!element.isFinal && !element.isConst) {
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - inconsistent braces. Since we are already omitting them in line 33, probably best to omit them throughout

    final expr = node.expression;
    if (expr is! SimpleIdentifier) return;

    final element = expr.element;
    if (element is! LocalVariableElement) return;

    if (!element.isFinal && !element.isConst) return;

    final block = node.parent;
    if (block == null) return;

final tokenBeforeReturn =
_returnStatement.findPrevious(_returnStatement.beginToken);
bool _isSimpleIdentifierImmutable(SimpleIdentifier identifier) {
switch (identifier.element) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure this will work

    return switch (identifier.element) {
      ClassElement _ => true,
      final VariableElement variable ||
      GetterElement(:final VariableElement variable) =>
        variable.isFinal || variable.isConst,
      _ => false
    };

but this should

    return switch (identifier.element) {
      ClassElement _ => true,
      final VariableElement variable => variable.isFinal || variable.isConst,
      GetterElement(:final PropertyInducingElement variable) =>
        variable.isFinal || variable.isConst,
      _ => false
    };

/// VariableDeclarationStatement doesn't count when visiting SimpleIdentifier.
/// Any other amount of variable mentions implies that it is used somewhere
/// except return, so its existence is justified.
static const _badStatementCount = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - I'd rather have static as the top-most in the class

int _variableStatementCounter = 0;

/// Defines whether the variables is used in return statement only.
bool hasBadStatementCount() =>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool hasBadStatementCount() =>
bool get hasBadStatementCount =>

Copy link
Copy Markdown
Contributor

@danylo-safonov-solid danylo-safonov-solid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@daria-trusca-solid daria-trusca-solid merged commit 2006202 into analysis_server_migration Jun 4, 2026
0 of 2 checks passed
@daria-trusca-solid daria-trusca-solid deleted the migrate_avoid_unnecessary_return_variable branch June 4, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants